import SparkMD5 from 'spark-md5'
import Pubsub from "pubsub-js";

const MAX_BLOB_SIZE = 1024 * 1024; // 默认分块：1MB

/**
 * 将file切片，每片大小为 {maxBlobSize}
 * @param file
 * @param maxBlobSize
 * @returns {[]} 文件切片
 */
export function splitFile(file, maxBlobSize= MAX_BLOB_SIZE) {
    if(! file instanceof File) {
        console.log('file is not a File object')
        return [];
    }
    let chunks = [];
    let count = Math.ceil(file.size / maxBlobSize);

    for (let i = 0; i < count; i++) {
        let chunk = file.slice(i * maxBlobSize, (i + 1) * maxBlobSize);
        chunks.push(chunk);
    }
    return chunks;
}

/**
 * 分块计算大文件MD5哈希值，必须引入spark-md5依赖
 * 会用Pubsub发布一个 'loading-md5' 事件，携带参数 {current, total}
 * @param file 文件
 * @param maxBlobSize 分块文件大小的最大值
 * @returns {Promise<unknown>} 异步返回
 */
export function calculateBigFileMD5(file, maxBlobSize = MAX_BLOB_SIZE) {
    return new Promise((resolve, reject) => {
        if(! file instanceof File) {
            reject('file is not a File object')
        }

        let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
        let chunks = Math.ceil(file.size / maxBlobSize)
        let currentChunk = 0
        let spark = new SparkMD5.ArrayBuffer()
        let fileReader = new FileReader();

        fileReader.onload = (e) => {
            Pubsub.publish('loading-md5', {
                current: currentChunk,
                total: chunks
            })
            spark.append(e.target.result)
            currentChunk++
            if (currentChunk < chunks) {
                loadNext()
            } else {
                Pubsub.publish('loading-md5', {
                    current: currentChunk,
                    total: chunks
                })
                resolve(spark.end())
            }
        }

        // 当发生错误时调用onerror事件
        fileReader.onerror = function () {
            reject('Failed to read file');
        };

        function loadNext() {
            let start = currentChunk * maxBlobSize
            let end = ((start + maxBlobSize) >= file.size) ? file.size : start + maxBlobSize
            fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
        }

        loadNext()
    })
}


export function getVideoDuration(videoFile) {
    return new Promise((resolve, reject) => {
        if(! videoFile instanceof File) {
            reject('file is not a File object')
        }
        const isVideoFile = /video\/(wmv|asf|asx|rm|rmvb|mpg|mpeg|mpe|3gp|mov|mp4|m4v|avi|dat|mkv|flv|vob|x-matroska|quicktime)$/.test(videoFile.type);
        if(! isVideoFile) {
            reject('file is not a video file')
        }
        const url = URL.createObjectURL(videoFile)
        const audioElement = new Audio(url)
        audioElement.addEventListener('loadedmetadata', function(event) {
            resolve(Math.floor(audioElement.duration))
        })
    })
}


